package com.sdy.resdir.web.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sdy.auth.client.service.SsoService;
import com.sdy.common.model.BizException;
import com.sdy.common.utils.Assert;
import com.sdy.common.utils.StringUtil;
import com.sdy.resdir.biz.mapper.RequirementInfoMapper;
import com.sdy.resdir.biz.model.FlowHistories;
import com.sdy.resdir.biz.model.ReplyInfo;
import com.sdy.resdir.biz.service.FlowHistoriesService;
import com.sdy.resdir.biz.service.ReplyInfoService;
import com.sdy.resdir.biz.service.RequirementInfoService;
import com.sdy.resdir.biz.model.RequirementInfo;
import com.sdy.common.model.Response;
import com.sdy.resdir.biz.vo.RequireOrReplyVO;
import com.sdy.usercenter.api.UserQueryApi;
import com.sdy.usercenter.api.dto.DeptDto;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import com.sdy.mvc.controller.BaseController;

import javax.servlet.http.HttpServletRequest;
import java.net.URLDecoder;
import java.util.*;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author glm
 * @since 2020-01-03
 */
@Slf4j
@RestController
@Api(tags = "互动交流-数据需求与问题反馈")
@SuppressWarnings("unchecked")
@RequestMapping("/requirementReply")
public class RequirementInfoController extends BaseController {
    @Autowired
    private RequirementInfoService requirementInfoService;
    @Autowired
    private FlowHistoriesService flowHistoriesService;
    @Autowired
    private SsoService ssoService;
    @Autowired
    private UserQueryApi userQueryApi;
    @Autowired
    private ReplyInfoService replyInfoService;
    @Value("${res.dept.code}")
    private String deptCode;

    @ApiOperation(value = "获取需求回复列表")
    @ApiImplicitParams(value = {
            @ApiImplicitParam(name = "需求名称", value = "requirementName"),
            @ApiImplicitParam(name = "需求状态(2.已回复 3.待处理 4.已流转)", value = "requirementState"),
            @ApiImplicitParam(name = "需求页面或者回复页面(1.需求页面 2.回复页面)", value = "requireOrReply")
    })
    @GetMapping("/getRequirementList")
    public Response getRequirementList(HttpServletRequest request, String requirementName, Integer requirementState, Integer requireOrReply) {
        if (StringUtil.isNotBlank(requirementName)) {
            requirementName = URLDecoder.decode(requirementName);
        }
        Integer userId = ssoService.getUserId(request);
        Integer ownDeptId = userQueryApi.getUser(userId).getOwnDeptId();
        IPage page = new Page();
        // 需求页面
        if (requireOrReply != null && requireOrReply == 1) {
            page = requirementInfoService.page(page, new LambdaQueryWrapper<RequirementInfo>()
                    .like(requirementName != null, RequirementInfo::getRequirementName, requirementName)
                    .eq(RequirementInfo::getRequireDeptId, ownDeptId)
                    .orderByDesc(RequirementInfo::getId));
            // 回复页面
        } else if (requireOrReply != null && requireOrReply == 2) {
            page = replyInfoService.page(page, new LambdaQueryWrapper<ReplyInfo>()
                    .like(StringUtil.isNotBlank(requirementName), ReplyInfo::getRequirementName, requirementName)
                    .eq(requirementState != null, ReplyInfo::getRequirementState, requirementState)
                    .eq(ReplyInfo::getReplyDeptId, ownDeptId)
                    .orderByDesc(ReplyInfo::getId));
        }
        return Response.success(page);
    }

    @ApiOperation("新增需求单")
    @PostMapping("/addRequirement")
    public Response addRequirement(@RequestBody @ApiParam(name = "requirementName & requirementType & instructionsDetail", value = "需求名称，需求类型(1.数据需求 2.问题反馈)，详细说明") RequirementInfo requirementInfo, HttpServletRequest request) throws BizException {
        Assert.isTrue(requirementInfo.getRequirementType() == 0 || requirementInfo.getRequirementType() == null, "请选择申请类型");
        Integer userId = ssoService.getUserId(request);
        Integer ownDeptId = userQueryApi.getUser(userId).getOwnDeptId();
        String ownDeptName = userQueryApi.getUser(userId).getOwnDeptName();
        DeptDto deptByCode = userQueryApi.getDeptByCode(deptCode);
        Date date = new Date();
        requirementInfo.setRequireDeptId(ownDeptId)
                .setRequireDeptName(ownDeptName)
                .setReplyDeptId(deptByCode.getId())
                .setReplyDeptName(deptByCode.getName())
                .setRequirementState(1)
                .setApplyTime(date);
        // 新增需求单
        boolean saveRequirementInfo = requirementInfoService.save(requirementInfo);
        Assert.notTrue(saveRequirementInfo, "新增需求失败");
        Integer requirementId = requirementInfo.getId();
        // 新增一条回复单
        boolean saveReplyInfo = replyInfoService.save(new ReplyInfo()
                .setRequirementId(requirementId)
                .setRequirementName(requirementInfo.getRequirementName())
                .setRequirementType(requirementInfo.getRequirementType())
                .setInstructionsDetail(requirementInfo.getInstructionsDetail())
                .setRequireDeptId(ownDeptId)
                .setRequireDeptName(ownDeptName)
                .setReplyDeptId(deptByCode.getId())
                .setReplyDeptName(deptByCode.getName())
                .setApplyTime(date)
                .setRequirementState(1));
        // 新增一条流转记录
        boolean saveFlowHistories = flowHistoriesService.save(new FlowHistories()
                .setFlowInitateDeptId(ownDeptId)
                .setFlowInitateDeptName(ownDeptName)
                .setFlowReceiveDeptId(deptByCode.getId())
                .setFlowReceiveDeptName(deptByCode.getName())
                .setFlowStartTime(date)
                .setRequirementId(requirementId)
                .setIsStart(1)
                .setFlowStartTime(date)
                .setRequirementState(1));
        return saveReplyInfo && saveFlowHistories ? Response.success() : Response.error();
    }

    @ApiOperation("获取单条需求详情及流转记录")
    @ApiImplicitParam(name = "requirementId", value = "需求id")
    @GetMapping("/getRequirementOrReplyDetail")
    public Response getRequirementOrReplyDetail(Integer requirementId) {
        // 获得申请单详情
        RequirementInfo requirementInfo = requirementInfoService.getById(requirementId);
        // 获得流转历史记录
        List<FlowHistories> flowHistories = flowHistoriesService.list(new LambdaQueryWrapper<FlowHistories>()
                .eq(FlowHistories::getRequirementId, requirementId)
                .orderByAsc(FlowHistories::getFlowStartTime));
        Map<String, Object> requirementOrReplyDetail = new HashMap<>(16);
        requirementOrReplyDetail.put("requirementReply", requirementInfo);
        requirementOrReplyDetail.put("flowHistories", flowHistories);
        return Response.success(requirementOrReplyDetail);
    }

    @ApiOperation("需求单流转或回复")
    @PostMapping("/requirementFlow")
    public Response requirementFlow(@RequestBody @ApiParam(name = "requirementId & flowReceiveDeptId & flowReceiveDeptName & flowReason & requirementState & replyInfo",
            value = "需求id，流转接收部门id,流转接受部门名称，流转发起原因，需求状态(1.待处理 2.已流转 3.已回复)，回复信息")
                                            RequireOrReplyVO requireOrReplyVO, HttpServletRequest request) throws BizException {
        Integer userId = ssoService.getUserId(request);
        Integer ownDeptId = userQueryApi.getUser(userId).getOwnDeptId();
        String ownDeptName = userQueryApi.getUser(userId).getOwnDeptName();
        Assert.isNull(userId, "用户未登录");
        // 获取该需求的信息
        RequirementInfo byId = requirementInfoService.getById(requireOrReplyVO.getRequirementId());
        Assert.isNull(byId, "该需求不存在");
        // 如果是流转
        if (requireOrReplyVO.getRequirementState() == 2) {
            Assert.isTrue(byId.getRequireDeptId().equals(requireOrReplyVO.getFlowReceiveDeptId()), "请勿将需求流转至需求申请部门");
            Assert.isTrue(ownDeptId.equals(requireOrReplyVO.getFlowReceiveDeptId()), "不能将需求流转到当前部门");
            // 获取流转目标是否接受过该条需求
            ReplyInfo oneReplyInfo = replyInfoService.getOne(new LambdaQueryWrapper<ReplyInfo>()
                    .eq(ReplyInfo::getRequirementId, requireOrReplyVO.getRequirementId())
                    .eq(ReplyInfo::getReplyDeptId, requireOrReplyVO.getFlowReceiveDeptId())
                    .eq(ReplyInfo::getReplyDeptName, requireOrReplyVO.getFlowReceiveDeptName()));
            boolean saveReplyInfo = true;
            // 如果是第一次接收，则新建一条回复单
            if (oneReplyInfo == null) {
                saveReplyInfo = replyInfoService.save(new ReplyInfo()
                        .setRequirementId(requireOrReplyVO.getRequirementId())
                        .setRequirementName(byId.getRequirementName())
                        .setRequireDeptId(byId.getRequireDeptId())
                        .setRequireDeptName(byId.getRequireDeptName())
                        .setReplyDeptId(requireOrReplyVO.getFlowReceiveDeptId())
                        .setReplyDeptName(requireOrReplyVO.getFlowReceiveDeptName())
                        .setRequirementState(1)
                        .setRequirementType(byId.getRequirementType())
                        .setApplyTime(byId.getApplyTime()));
                // 如果不是第一次接收该需求，则把之前该部门的该条需求单的状态改为待处理
            } else {
                saveReplyInfo = replyInfoService.update(new LambdaUpdateWrapper<ReplyInfo>()
                        .eq(ReplyInfo::getRequirementId, requireOrReplyVO.getRequirementId())
                        .eq(ReplyInfo::getReplyDeptId, requireOrReplyVO.getFlowReceiveDeptId())
                        .eq(ReplyInfo::getReplyDeptName, requireOrReplyVO.getFlowReceiveDeptName())
                        .set(ReplyInfo::getRequirementState, 1));
            }
            // 流转之后将我的这条需求回复单状态改为已流转
            boolean updateReplyInfo = replyInfoService.update(new LambdaUpdateWrapper<ReplyInfo>()
                    .eq(ReplyInfo::getReplyDeptId, ownDeptId)
                    .eq(ReplyInfo::getReplyDeptName, ownDeptName)
                    .eq(ReplyInfo::getRequirementId, requireOrReplyVO.getRequirementId())
                    .set(ReplyInfo::getRequirementState, requireOrReplyVO.getRequirementState()));
            // 创建一条该需求的流转记录
            boolean saveFlowHistories = flowHistoriesService.save(new FlowHistories()
                    .setRequirementId(requireOrReplyVO.getRequirementId())
                    .setFlowInitateDeptId(ownDeptId)
                    .setFlowInitateDeptName(ownDeptName)
                    .setFlowReceiveDeptId(requireOrReplyVO.getFlowReceiveDeptId())
                    .setFlowReceiveDeptName(requireOrReplyVO.getFlowReceiveDeptName())
                    .setFolwReason(requireOrReplyVO.getReplyInfo())
                    .setRequirementState(1)
                    .setIsStart(0)
                    .setFlowStartTime(new Date())
                    .setFolwReason(requireOrReplyVO.getFlowReason()));
            return saveReplyInfo && saveFlowHistories && updateReplyInfo ? Response.success("需求流转成功") : Response.error("需求流转失败");
            // 如果是回复
        } else if (requireOrReplyVO.getRequirementState() == 3) {
            // 将需求单改为已回复，并加入回复信息
            boolean updateRequirementInfo = requirementInfoService.update(new LambdaUpdateWrapper<RequirementInfo>()
                    .eq(RequirementInfo::getId, requireOrReplyVO.getRequirementId())
                    .set(RequirementInfo::getRequirementState, 2)
                    .set(RequirementInfo::getReplyInfo, requireOrReplyVO.getReplyInfo())
                    .set(RequirementInfo::getReplyDeptId, ownDeptId)
                    .set(RequirementInfo::getReplyDeptName, ownDeptName));
            // 将本部门的这条回复单状态改为已回复，并加入回复信息
            boolean updateReplyInfo = replyInfoService.update(new LambdaUpdateWrapper<ReplyInfo>()
                    .eq(ReplyInfo::getRequirementId, requireOrReplyVO.getRequirementId())
                    .eq(ReplyInfo::getReplyDeptId, ownDeptId)
                    .eq(ReplyInfo::getReplyDeptName, ownDeptName)
                    .set(ReplyInfo::getReplyInfo, requireOrReplyVO.getReplyInfo())
                    .set(ReplyInfo::getRequirementState, requireOrReplyVO.getRequirementState()));
            FlowHistories myFlow = flowHistoriesService.getOne(new LambdaQueryWrapper<FlowHistories>()
                    .eq(FlowHistories::getRequirementId, requireOrReplyVO.getRequirementId())
                    .eq(FlowHistories::getFlowReceiveDeptId, ownDeptId)
                    .eq(FlowHistories::getRequirementState, 1));
            // 新建一条与流转到我的需求单相同的历史，并将状态改为已回复
            boolean updateFlowHistories = flowHistoriesService.save(myFlow.setRequirementState(requireOrReplyVO.getRequirementState()).setIsStart(0).setFlowStartTime(new Date()));
            return updateFlowHistories && updateReplyInfo && updateRequirementInfo ? Response.success("回复成功") : Response.error("回复失败");
        } else {
            return Response.error("无法获取操作类型");
        }
    }
}
